package com.zx.rbac.common.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zx.rbac.common.annotation.PermissionVerify;
import com.zx.rbac.common.api.IResultCode;
import com.zx.rbac.common.api.Result;
import com.zx.rbac.common.exception.RRException;
import com.zx.rbac.common.service.RedisService;
import com.zx.rbac.common.util.ObjectToListUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.ObjectUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

/**
 * @author :xxx
 * @description:TODO
 * @date :2021/8/9 19:34
 */
@Component
@Aspect //声明切面
@Slf4j
public class PermissionVerifyAspect {

    @Autowired
    RedisService redisService;

    //声明切点
    @Pointcut("@annotation(com.zx.rbac.common.annotation.PermissionVerify)")
    public void verifyAround( ){
    }

    //定义环绕增强
    @Around("verifyAround()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //获取连接点上的注解
        PermissionVerify statistic = method.getAnnotation(PermissionVerify.class);
        //获取此次请求对象
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) Objects.requireNonNull(
                RequestContextHolder.getRequestAttributes());
        HttpServletRequest request = servletRequestAttributes.getRequest();
        //获取用户角色ids
        String token = request.getHeader("token");
        Object o = redisService.get(token);
        if(ObjectUtils.defaultIfNull(o,null)==null){
            throw new RRException(IResultCode.UNAUTHORIZED);
        }
        String adminJson = (String)o;
        JSONObject jsonObject = JSON.parseObject(adminJson);
        Object object = jsonObject.get("roleIds");
        List<Long> roleIds = ObjectToListUtil.objToList(object, Long.class);
        //判断角色知否包含权限
        for (Long item : roleIds) {
            Object o1 = redisService.get("roleId#" + roleIds);
            if (ObjectUtils.defaultIfNull(o1, null) != null) {
                List<String> pValues = ObjectToListUtil.objToList(o1, String.class);
                if (pValues.contains(statistic.value())) {
                    return joinPoint.proceed();
                }
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("方法{}执行完毕，耗时:{}ms",method.getName(),endTime-startTime);
        return Result.failed(IResultCode.FORBIDDEN);
    }

}
